﻿using System.Text;
using CodeAgent.Host.Context;
using CodeAgent.Host.Service;
using Microsoft.AspNetCore.SignalR;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Chat;
using Microsoft.SemanticKernel.ChatCompletion;

#pragma warning disable SKEXP0001

#pragma warning disable SKEXP0110

namespace CodeAgent.Host.Agents;

public class AgentManager : IAsyncDisposable
{
    private readonly AsyncServiceScope _asyncServiceScope;
    private readonly string _userId;
    public readonly string AgentId;
    private AgentOption? _options;
    private readonly IHubContext<CodeAgentHub> _hubContext;
    private readonly ILogger<AgentManager> _logger;
    private readonly CancellationTokenSource _cancellationTokenSource = new();
    private AgentGroupChat chat;
    private List<ChatMessageContent> chatHistory = new();
    private readonly string _connectionId;

    public AgentManager(AsyncServiceScope asyncServiceScope, string userId, string connectionId)
    {
        _connectionId = connectionId;
        this._asyncServiceScope = asyncServiceScope;
        this._userId = userId;
        AgentId = Guid.NewGuid().ToString();

        _hubContext = asyncServiceScope.ServiceProvider.GetRequiredService<IHubContext<CodeAgentHub>>();
        _logger = asyncServiceScope.ServiceProvider.GetRequiredService<ILogger<AgentManager>>();

        _logger.LogInformation("AgentManager初始化完成，连接Id：{connectionId} AgentId:{agentIdd} connection:{connectionId}",
            userId, AgentId, connectionId);
    }

    /// <summary>
    /// 初始化配置
    /// </summary>
    /// <param name="options"></param>
    public async Task Initialize(AgentOption options)
    {
        _options = options;

        _logger.LogInformation("AgentManager配置初始化完成，连接Id：{connectionId} AgentId:{agentIdd}", _userId, AgentId);

        if (!Check())
        {
            await _hubContext.Clients.Client(_connectionId)
                .SendAsync("AgentProtocol", new AgentProtocol<string>()
                {
                    type = "error",
                    result = "配置错误",
                    code = 500,
                    agentName = "AgentManager",
                    agentId = AgentId
                });
            return;
        }
    }

    public bool Check()
    {
        if (_options is null)
        {
            return false;
        }

        if (string.IsNullOrWhiteSpace(_options.ApiKey))
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// 开始对话
    /// </summary>
    /// <param name="message"></param>
    public async Task StartGroup(ChatMessageContent message, string model)
    {
        AgentContext.Current = new AgentContextStorage
        {
            ConfirmAction = async (result) =>
            {
                result = await _hubContext.Clients.Client(_connectionId)
                    .InvokeCoreAsync<string>("NotifyUserTaskDone", [result], _cancellationTokenSource.Token);

                return result;
            },
            NotifyAction = async (result) =>
            {
                await _hubContext.Clients.Client(_connectionId)
                    .SendAsync("AgentConsole", new AgentProtocol<AgentConsoleProtocol>()
                    {
                        type = "notify",
                        result = result,
                        code = 200,
                        agentName = "AgentManager",
                        agentId = AgentId
                    });
            }
        };

        var admin = AdminAgent.CreateAdminAgent(_options!, model);
        // var docker = DockerAgent.CreateDockerAgent(_options!, _userId, model);
        var code = CodeAgent.CreateCodeAgent(_options!, _userId);

        chat = new AgentGroupChat(admin, code)
        {
            ExecutionSettings = new AgentGroupChatSettings()
            {
                TerminationStrategy = new AgentTerminationStrategy(chatHistory)
                {
                    Agents = [admin],
                    MaximumIterations = 200,
                    AutomaticReset = true,
                }
            }
        };

        chatHistory.Add(message);

        chat.AddChatMessages(chatHistory);

        var agentName = string.Empty;
        var agentId = Guid.NewGuid().ToString();

        var sb = new StringBuilder();
        await foreach (var item in chat.InvokeStreamingAsync(_cancellationTokenSource.Token))
        {
            if (agentName != item.AuthorName)
            {
                if(sb.Length > 0)
                {
                    await _hubContext.Clients.Client(_connectionId)
                        .SendAsync("AgentProtocol", new AgentProtocol<string>()
                        {
                            type = "text",
                            result = sb.ToString(),
                            code = 200,
                            agentName = agentName,
                            agentId = agentId
                        });
                }
                
                agentId = Guid.NewGuid().ToString();
                sb.Clear();
            }

            if (item.Role == AuthorRole.Assistant)
            {
                sb.Append(item.Content);

                // 如果是AI回复则通知前端
                await _hubContext.Clients.Client(_connectionId)
                    .SendAsync("AgentProtocol", new AgentProtocol<string>()
                    {
                        type = "text",
                        result = sb.ToString(),
                        code = 200,
                        agentName = item.AuthorName!,
                        agentId = agentId
                    });
            }

            agentName = item.AuthorName!;
            Console.WriteLine("AgentManager: " + item.Content);
        }
    }


    public async ValueTask DisposeAsync()
    {
        _logger.LogInformation("AgentManager释放资源，连接Id：{connectionId} AgentId:{agentIdd}", _userId, AgentId);

        await _asyncServiceScope.DisposeAsync();

        await _cancellationTokenSource.CancelAsync();
    }
}